4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
16 namespace Microsoft
.JScript
{
18 using Microsoft
.JScript
.Vsa
;
20 using System
.Reflection
;
21 using System
.Reflection
.Emit
;
22 using System
.Globalization
;
24 internal sealed class RegExpLiteral
: AST
{
25 private String source
;
26 private bool ignoreCase
, global, multiline
;
27 private JSGlobalField regExpVar
;
29 private static int counter
= 0;
32 internal RegExpLiteral(String source
, String flags
, Context context
)
35 this.ignoreCase
= this.global = this.multiline
= false;
37 for (int i
= 0; i
< flags
.Length
; i
++)
41 throw new JScriptException(JSError
.RegExpSyntax
);
42 this.ignoreCase
= true;
46 throw new JScriptException(JSError
.RegExpSyntax
);
51 throw new JScriptException(JSError
.RegExpSyntax
);
52 this.multiline
= true;
55 throw new JScriptException(JSError
.RegExpSyntax
);
59 internal override Object
Evaluate() {
60 if( VsaEngine
.executeForJSEE
)
61 throw new JScriptException(JSError
.NonSupportedInDebugger
);
62 RegExpObject regExpObject
= (RegExpObject
)Globals
.RegExpTable
[this];
63 if (regExpObject
== null) {
64 regExpObject
= (RegExpObject
)this.Engine
.GetOriginalRegExpConstructor().Construct
65 (this.source
, this.ignoreCase
, this.global, this.multiline
);
66 Globals
.RegExpTable
[this] = regExpObject
;
71 internal override IReflect
InferType(JSField inferenceTarget
){
72 return Typeob
.RegExpObject
;
75 internal override AST
PartiallyEvaluate() {
76 String id
= "regexp "+(RegExpLiteral
.counter
++).ToString(CultureInfo
.InvariantCulture
);
77 GlobalScope gs
= (GlobalScope
)this.Engine
.GetGlobalScope().GetObject();
78 JSGlobalField v
= (JSGlobalField
)gs
.AddNewField(id
, null, FieldAttributes
.Assembly
);
79 v
.type
= new TypeExpression(new ConstantWrapper(Typeob
.RegExpObject
, this.context
));
84 internal override void TranslateToIL(ILGenerator il
, Type rtype
) {
85 il
.Emit(OpCodes
.Ldsfld
, (FieldInfo
)this.regExpVar
.GetMetaData());
86 Convert
.Emit(this, il
, Typeob
.RegExpObject
, rtype
);
89 internal override void TranslateToILInitializer(ILGenerator il
) {
90 ScriptObject scope
= this.Engine
.ScriptObjectStackTop();
91 while (scope
!= null && (scope
is WithObject
|| scope
is BlockScope
))
92 scope
= scope
.GetParent();
93 if (scope
is FunctionScope
){
94 this.EmitILToLoadEngine(il
); //Make sure engine gets initialized every time function is entered
97 il
.Emit(OpCodes
.Ldsfld
, (FieldInfo
)this.regExpVar
.GetMetaData());
98 Label exit
= il
.DefineLabel();
99 il
.Emit(OpCodes
.Brtrue_S
, exit
);
100 this.EmitILToLoadEngine(il
);
101 il
.Emit(OpCodes
.Call
, CompilerGlobals
.getOriginalRegExpConstructorMethod
);
102 il
.Emit(OpCodes
.Ldstr
, this.source
);
104 il
.Emit(OpCodes
.Ldc_I4_1
);
106 il
.Emit(OpCodes
.Ldc_I4_0
);
108 il
.Emit(OpCodes
.Ldc_I4_1
);
110 il
.Emit(OpCodes
.Ldc_I4_0
);
112 il
.Emit(OpCodes
.Ldc_I4_1
);
114 il
.Emit(OpCodes
.Ldc_I4_0
);
115 il
.Emit(OpCodes
.Call
, CompilerGlobals
.regExpConstructMethod
);
116 il
.Emit(OpCodes
.Castclass
, Typeob
.RegExpObject
);
117 il
.Emit(OpCodes
.Stsfld
, (FieldInfo
)this.regExpVar
.GetMetaData());